<template>
  <a-layout style="width: 1200px">
    <a-layout-header style="background: #fff; padding: 0">
      <h1>人脸识别校验</h1>
    </a-layout-header>
    <a-layout-content style="margin: 24px 16px 0;">
      <video ref="video" :width="640" :height="480" autoplay></video>
      <br/>

      <a-button type="primary" @click="startPrediction">签到/签退</a-button>
      <a-button danger @click="stopPrediction">停止识别</a-button>
      <div ref="result">{{ predictionResult }}</div>
    </a-layout-content>
  </a-layout>
</template>

<script>
import { Button, message } from 'ant-design-vue';
import myAxios from "../plugins/myAxios.ts";

export default {
  name: 'VideoPrediction',
  components: {
    'a-button': Button,
  },
  data() {
    return {
      stream: null,
      isPredicting: false,
      predictions: [],
      predictionResult: '',
    };
  },
  mounted() {
    this.setupCamera();
  },
  methods: {
    async setupCamera() {
      try {
        this.stream = await navigator.mediaDevices.getUserMedia({ video: true });
        this.$refs.video.srcObject = this.stream;
      } catch (error) {
        message.error('摄像头获取失败');
        console.error('摄像头获取失败', error);
      }
    },

    captureFrame() {
      if (!this.isPredicting) return;
      const canvas = document.createElement('canvas');
      canvas.width = 640;
      canvas.height = 480;
      const context = canvas.getContext('2d');
      context.drawImage(this.$refs.video, 0, 0, canvas.width, canvas.height);
      canvas.toBlob(async (blob) => {
        const formData = new FormData();
        formData.append('image', blob, 'frame.jpg');


        const response = await fetch("https://u277885-83ae-77241419.neimeng.seetacloud.com:6443/predict", {
          method: "POST",
          body: formData,
          headers: {
            'Accept': 'application/json'
          }
        });

        const result = await response.json();

        if (response.ok) {
          this.predictions.push(result.label);

          if (this.predictions.length > 5) {
            this.predictions.shift();
          }

          const counts = this.predictions.reduce((acc, cur) => ({ ...acc, [cur]: (acc[cur] || 0) + 1 }), {});
          const maxLabel = Object.keys(counts).reduce((a, b) => counts[a] > counts[b] ? a : b);
          function isValidNumberFormat(str) {
            // 此正则表达式匹配整数和浮点数，包括正负号和科学记数法
            const numberPattern = /^[-+]?(?:\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?$/;
            return numberPattern.test(str);
          }
          if (counts[maxLabel] >= 3) {
            this.isPredicting = false;
            this.predictionResult = `${maxLabel}签到成功`;
            if(!isValidNumberFormat(maxLabel)){
              message.error(`错误: 识别失败，error person！`);
            }

            const file = new FormData();
            file.append('file', blob, maxLabel); // 重新添加 blob 文件

            myAxios.post("/user/signInOrOut",file).then(res=> {
              console.log(res)
              if (res.code === 0){
                message.success(res.description || res.message);
                this.predictionResult = res.description || res.message;
              }else {
                message.error(res.description || res.message || '未知错误');
                this.predictionResult = res.description || res.message;
              }
            })
            this.stopPrediction();
          }
        } else {
          this.predictionResult = `错误: 识别失败，error person！`;
        }

        setTimeout(this.captureFrame, 1000);
      }, 'image/jpeg');
    },


    stopPrediction() {
      this.isPredicting = false;
      if (this.stream) {
        this.stream.getTracks().forEach(track => {
          track.stop();
          track = null;
        });
        this.stream = null;
      }
      this.$refs.video.srcObject = null;
    },

    async startPrediction() {
      this.isPredicting = true;
      this.predictions = [];
      this.predictionResult = '';

      // 在开始预测前，尝试重新获取媒体流
      try {
        if (this.stream) {
          // 如果已有流，先释放
          this.stream.getTracks().forEach(track => track.stop());
        }
        this.stream = await navigator.mediaDevices.getUserMedia({ video: true });
        this.$refs.video.srcObject = this.stream;
      } catch (error) {
        this.isPredicting = false; // 确保状态重置
        message.error('摄像头获取失败');
        console.error('摄像头获取失败', error);
        return;
      }
      this.captureFrame();
    },

  },
};
</script>

<style scoped>
/* 样式可以根据需要添加 */
</style>
